/*
 * Copyright (c) 2011 Ondrej Lapacek
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

/**
 * @author      Ondrej Lapacek
 * @version     1.0, 09/12/11
 * @since       1.0
 */

package cz.muni.fi.android.assistivecamera;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.concurrent.ExecutionException;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.hardware.Camera;
import android.location.Location;
import android.location.LocationManager;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.PowerManager;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import cz.muni.fi.android.assistivecamera.camera.CameraPreview;
import cz.muni.fi.android.assistivecamera.camera.CameraShutter;
import cz.muni.fi.android.assistivecamera.dialog.BlindDialog;
import cz.muni.fi.android.assistivecamera.dialog.ResponseEventListener;
import cz.muni.fi.android.assistivecamera.entities.Building;
import cz.muni.fi.android.assistivecamera.gallery.AssistiveGalleryActivity;
import cz.muni.fi.android.assistivecamera.hardware.HardwareFeatures;
import cz.muni.fi.android.assistivecamera.intersectiondetector.IntersectionDetector;
import cz.muni.fi.android.assistivecamera.location.GPSReader;
import cz.muni.fi.android.assistivecamera.osm.OpenStreetMap;
import cz.muni.fi.android.assistivecamera.osm.OpenStreetMapDownloadTask;
import cz.muni.fi.android.assistivecamera.osm.model.Node;
import cz.muni.fi.android.assistivecamera.osm.model.OsmData;
import cz.muni.fi.android.assistivecamera.osm.model.Way;
import cz.muni.fi.android.assistivecamera.sensor.OrientationListener;
import cz.muni.fi.android.assistivecamera.sensor.OrientationManager;
import cz.muni.fi.android.assistivecamera.texttospeech.SpeechHandler;

public class AssistiveCameraActivity extends Activity implements OrientationListener, ResponseEventListener {
	
	private static final double EARTH_RADIUS = 6371.0;
	
    private CameraPreview mPreview = null;
    private Camera mCamera = null;
    
	@SuppressWarnings("unused")
	private GPSReader myGPSReader = null;
    private boolean GPSReaderIsBound = false;
    
    private float horizontalViewAngle = -1;
    
    private float viewAngle = -1;
    private float azimuth = -1;
    private Location location = null;
    
    private float tempViewAngle = -1;
    private float tempAzimuth = -1;
    private Location tempLocation = null;
    
    private GestureDetector mGestureDetector = null;

	private OsmData visibleBuildings;
    
    private static Context ctx;
    
    private Dialog dataDialog = null;
    private CameraShutter camShutter = null;
    private LogicThread task = null;
    
    private boolean isShutterReady = true;
    
    private PowerManager.WakeLock wakeLocker = null;
    
    private Vibrator vib = null;
    
    private String gpsStatus = null;
    
    private boolean isGalleryStarted = false;
    
    private BlindDialog customizeDialog = null;
    
    private MediaPlayer mpButton = null; 
    
    private static final String TAG = "Blind Photo Activity";	
    
    private String buildingName;

    @Override
    protected void onActivityResult(int requestCode,
    		int resultCode,Intent result){
    	Log.d(TAG,"Request Code:" + requestCode);
    	Log.d(TAG, "Result Code:" + resultCode);
    	SpeechHandler.ttsQueue("request code is " + requestCode + "and result code is "+resultCode, 1, 1);
    	
    	if(requestCode == 1){
    		if(resultCode == RESULT_OK){
    			buildingName = result.getExtras().getString("Building");
    			System.out.println("Building: " + buildingName);
    			Log.d(TAG,"Acquired building name:" + buildingName);
    			if(tempLocation == null){
    				tempLocation = location;
    			}
    			Log.d(TAG,"Current location: " + tempLocation);
    			SpeechHandler.ttsQueue("Building "+ buildingName, 1, 1);
    			SpeechHandler.ttsQueue(getResources().getString(R.string.gettingBuildingLocation),1,1);
    			Building building = OpenStreetMap.getBuildingInfo(ctx, buildingName,tempLocation);
    			if(building == null){
    				SpeechHandler.ttsQueue(getResources().getString(R.string.buildingNotFound), 1, 1);
    			}else{
    				double distance = getDistance(building);
    				if(distance<200){
    					double buildingAzimuth = getAzimuth(building);
    					Log.d(TAG,"Building azimuth:" + buildingAzimuth);
    					SpeechHandler.ttsQueue(getResources().getString(R.string.Rotation)+(buildingAzimuth - azimuth)+getResources().getString(R.string.degree), 1, 1);
    					/**
    					 * TODO Doplnit rotaci smerem k objektu.
    					 */
    				}else{
    					SpeechHandler.ttsQueue(getResources().getString(R.string.toDistantBuilding), 1, 1);
    				}
    			}
    		}
    	}
    	
    }
    public boolean onTouchEvent(MotionEvent event){
    	switch(event.getAction()){
    		case MotionEvent.ACTION_UP:
    				Log.d(TAG, "Starting dialog on key event");
    				if (tempLocation != null || location != null){
    					/*Intent locationActivity = new Intent(AssistiveCameraActivity.this,
    					cz.muni.fi.android.assistivecamera.ObjectLocatorActivity.class);
    					startActivity(locationActivity);
    					*/
    				  //  onSearchRequested();
    				}else{
    					SpeechHandler.ttsQueue(getResources().getString(R.string.gpsWait), 1, 1);
    					Log.d(TAG,"location = " + location + ", tempLocation = " + tempLocation);
    				}
    	}
    	return GPSReaderIsBound;
    }
    /**
     * Calculates distance to the building
     * @param building searched building
     * @return the distance to the building in meters
     */
    private double getDistance(Building building) {
		double deltaLat = building.getLocation().getLatitude() - tempLocation.getLatitude();
		double deltaLatRad = deltaLat * Math.PI / 180;
		double deltaLong = building.getLocation().getLongitude() - tempLocation.getLongitude();
		double deltaLongRad = deltaLong * Math.PI / 180;
		
		double a = Math.sin(deltaLatRad)*Math.sin(deltaLatRad)+ 
				Math.cos(building.getLocation().getLatitude()*Math.PI/180)*Math.cos(tempLocation.getLatitude()*Math.PI/180) +
				Math.sin(deltaLongRad)*Math.sin(deltaLongRad);
		double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
		double distance = c*EARTH_RADIUS;
		return distance;
	}

    /**
     * Calculates azimuth to the building
     * @param building searched building
     * @return azimuth in degrees
     */
	private double getAzimuth(Building building) {
		double diffLatitude = 0.0;
		double diffLongitude = 0.0;
		
		diffLatitude = building.getLocation().getLatitude() - tempLocation.getLatitude();
		diffLongitude = building.getLocation().getLongitude() - tempLocation.getLongitude();
		
		double arcTan = diffLongitude / diffLatitude;
		double angle = Math.atan(arcTan);
		if(diffLatitude<0) angle +=180;
		return angle;
	}

	@Override 
    public boolean onSearchRequested(){
    	Log.d(TAG, "Starting dialog");
		Intent locationActivity = new Intent(AssistiveCameraActivity.this,
				ObjectLocatorActivity.class);
		startActivityForResult(locationActivity,1);
		Log.d(TAG,"Dialog finished");
		return true;
    }
    
    @Override
	protected void onCreate(Bundle savedInstanceState) {
    	
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ctx = this;
        
        // Create our CameraPreview view and set it as the content of our activity.
        mPreview = new CameraPreview(this);
        
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLocker = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, TAG);
        
        vib = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
        mpButton = MediaPlayer.create(getBaseContext(), R.raw.button_click); 
        
        @SuppressWarnings("unused")
		HardwareFeatures featre = new HardwareFeatures(ctx);

        mPreview.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                return mGestureDetector.onTouchEvent(event);
            }
        });
        
        mGestureDetector = new GestureDetector(this.getApplicationContext(), new GestureDetector.SimpleOnGestureListener() {
            @Override
            public void onLongPress(MotionEvent e) {
                gallery();
            }
 
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                photo();
                return true;
            }
            
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
            	info();
                return true;
            }
 
            @Override
            public boolean onDown(MotionEvent e) {
            	mpButton.start();
                return true;
            }
        });
        mGestureDetector.setIsLongpressEnabled(true);
    }
    
    private void photo() {
    	if (isShutterReady) {
			task = new LogicThread();
			task.execute();
		}
    }
    
    private void gallery() {
    	isGalleryStarted = true;
        Intent intent = new Intent(AssistiveCameraActivity.this, AssistiveGalleryActivity.class);
        startActivity(intent);
    }
    
    private void info() {
    	String cardinal = null;
        if (gpsStatus != null) {
        	SpeechHandler.ttsQueue(getResources().getString(R.string.gpsStatus) + " " + gpsStatus, 1, 1);
        } else {
        	SpeechHandler.ttsQueue(getResources().getString(R.string.gpsStatusNotAvailable), 1, 1);
        }
        
        cardinal = headingToString(azimuth);
        SpeechHandler.ttsQueue(getResources().getString(R.string.compassStatus) + " " + cardinal, 1, 1);
    }
    
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
    	super.onKeyDown(keyCode, keyEvent);
		switch (keyCode) {
	    	case KeyEvent.KEYCODE_P : 
	    		mpButton.start();
	    		photo();	
	    		return true;
	        case KeyEvent.KEYCODE_G : 
	        	mpButton.start();
	        	gallery();	
	        	return true;
	        case KeyEvent.KEYCODE_I : 
	        	mpButton.start();
	        	info();	
	        	return true;
	        case KeyEvent.KEYCODE_SEARCH:
	        	Log.d(TAG, "Starting dialog on key event");
	        	if (tempLocation != null || location != null){
	    		/*Intent locationActivity = new Intent(AssistiveCameraActivity.this,
	    				cz.muni.fi.android.assistivecamera.ObjectLocatorActivity.class);
	    		startActivity(locationActivity);
	    		*/
	        		onSearchRequested();
	        	}else{
	        		SpeechHandler.ttsQueue(getResources().getString(R.string.gpsWait), 1, 1);
	        		Log.d(TAG,"location = " + location + ", tempLocation = " + tempLocation);
	        	}
	    		return true; 
		}
		return true;
	}
    
   
    
    public static String headingToString(float x) {
    	String directions[] = ctx.getResources().getStringArray(R.array.directions);
        return directions[ (int)Math.round((  ((float)x % 360) / 45)) ];
    }
    
    public static Context getContext() {
        return ctx;
    }
    
    OnCancelListener cancelListener = new OnCancelListener(){
        public void onCancel(DialogInterface dialog) {
        	cancelTask();
        }
	};
	
	public void cancelTask() {
    	task.cancel(true);
    	if (isShutterReady) {
    		camShutter.deleteLastPicture();
    	}
    	SpeechHandler.ttsQueue(getResources().getString(R.string.taskCancel), 0, 1);
	}
	
	private class LogicThread extends AsyncTask<Void, Void, Void> {
		@Override
	    protected void onPreExecute() {
			isShutterReady = false;
			tempViewAngle = -1;
			tempAzimuth = -1;
			tempLocation = null;
		    
		    tempViewAngle = viewAngle;
		    tempAzimuth = azimuth; 
		    tempLocation = location;
		    
		    SpeechHandler.ttsQueue(getResources().getString(R.string.wait), 1, 0);
		    SpeechHandler.ttsQueue(getResources().getString(R.string.dataProcessing), 1, 0);
		    dataDialog = ProgressDialog.show(AssistiveCameraActivity.this, 
		    		getResources().getString(R.string.wait), 
        			getResources().getString(R.string.dataProcessing));
	    }
		
		@Override
		protected Void doInBackground(Void... params) {
			while (tempAzimuth == -1) {
				tempAzimuth = azimuth; 
			}
			
			camShutter = new CameraShutter(mCamera, ctx);
			
			while (!camShutter.isReady()) {
			}
			dataDialog.setCancelable(true);
			dataDialog.setOnCancelListener(cancelListener);
			isShutterReady = camShutter.isReady();
			
			long startTime = System.currentTimeMillis();
			long millis = -1;
			
			/*Location loc = new Location("Assistive Camera");
			loc.setLongitude((float)16.606578);
			loc.setLatitude((float)49.193978);
			location = new Location(loc);*/
			
			Log.d(TAG,"azimuth" + azimuth);
			
			while (tempLocation == null) { 
				tempLocation = location; 
				millis = System.currentTimeMillis()-startTime;
				if (millis >= 30000) {
					SpeechHandler.ttsQueue(getResources().getString(R.string.timeLimitGps), 1, 1);
					SpeechHandler.ttsQueue(getResources().getString(R.string.taskCancel), 1, 1);
			    	if (isShutterReady) {
			    		camShutter.deleteLastPicture();
			    	}
			    	return null;

				}
				if (isCancelled()) return null;
			}
			
			AssistiveCameraActivity.this.runOnUiThread(mainRunThread);
			
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			dataDialog.dismiss();
		}
	}
	
	Runnable mainRunThread = new Runnable() {
		@Override
		public void run() {
	        
	        dataDialog.hide();
	        new OpenStreetMapDownloadTask(ctx, tempLocation, tempAzimuth, tempViewAngle) {
	            ProgressDialog downloadDialog;

	            @Override
	            protected void onPreExecute() {
	            	if(!myGPSReader.getProvider().equals(LocationManager.GPS_PROVIDER)){
	            		//SpeechHandler.ttsQueue(getResources().getString(R.string.wrongProvider), 1, 0);
	            		Log.d(TAG,"Wrong location provider: "+myGPSReader.getProvider());
	            	}
	    		    SpeechHandler.ttsQueue(getResources().getString(R.string.wait), 1, 0);
	    		    SpeechHandler.ttsQueue(getResources().getString(R.string.dataLoading), 1, 0);
	            	downloadDialog = ProgressDialog.show(AssistiveCameraActivity.this, 
	            			getResources().getString(R.string.wait), 
	            			getResources().getString(R.string.dataLoading));
	            }

	            @Override
	            protected void onPostExecute(OsmData result) {
	            	
	            	if (result != null) {
	            	
		            	if (result.getWays().size() == 0) {
		            		SpeechHandler.ttsQueue(getResources().getString(R.string.buildingsNotFound), 1, 1);
		            	} else {
		            		IntersectionDetector interTask = new IntersectionDetector();
			            	visibleBuildings = interTask.intersection(result, tempLocation, tempAzimuth, tempViewAngle);

			            	if (visibleBuildings.getWays().size() == 0) {
			            		SpeechHandler.ttsQueue(getResources().getString(R.string.visBuildingsNotFound), 1, 1);
			            	} else {
			            		Iterator<Entry<Long, Way>> wayIterator = visibleBuildings.getWays().entrySet().iterator();
			            		int counter = 0;
			            		
			        	    	while (wayIterator.hasNext()) {
			        	        	Map.Entry<Long, Way> wayRecord = wayIterator.next();
			            	    	Map<String,Object> wayData = new TreeMap<String,Object>(wayRecord.getValue().getTags());
			            	    	wayData.put("position", calculatePosition(wayRecord.getValue()));
			            	    	camShutter.loadExifData(wayData);
			            	    	
			            	    	
			            	    	SpeechHandler.ttsQueue(getResources().getString(R.string.building) + " " + ++counter, 1, 1);
			            	    	
			    				    String[] tags = ctx.getResources().getStringArray(R.array.tags);
			    				    String[] names = ctx.getResources().getStringArray(R.array.nameOfTags);
			    				    for(int j= 0 ; j< tags.length; j++) {
			    				    	if (wayRecord.getValue().getTag(tags[j]) != null) {
				            	    		if (wayRecord.getValue().getTag(tags[j]) != null) {
				            	    			if (tags[j].equals("distance")) {
				            	    				int distance = Integer.valueOf(wayRecord.getValue().getTag(tags[j]).toString());
				            	    				String distanceInMeters = ctx.getResources().getQuantityString(R.plurals.distanceInMeters, 
				            	    						distance, distance);
				            	    				SpeechHandler.ttsQueue(names[j] + " " + distanceInMeters, 1, 1);
					            	    	 	} else {
					            	    	 		SpeechHandler.ttsQueue(names[j] + " " + wayRecord.getValue().getTag(tags[j]), 1, 1);
					            	    	 	}
					            	    	}
				            	    	}
			    		            }
			        	        }
			        	    	Map<String,Object> position = new HashMap<String,Object>();
			        	    	JSONObject pos = new JSONObject();
			        	    	try{
			        	    		
			        	    		pos.put("latitude", ""+location.getLatitude());
			        	    		pos.put("longitude",""+location.getLongitude());
			        	    		pos.put("azimuth",""+azimuth);
			        	    		pos.put("accuracy",""+location.getAccuracy());
			        	    		pos.put("horizontal",""+horizontalViewAngle);
			        	    	}catch(JSONException ex){
			        	    		
			        	    	}
			        	    	position.put("cameraposition",pos);
			        	    	camShutter.loadExifData(position);
			        	    	camShutter.saveExifData();
			        	    }
		            	}
	            	}
		            downloadDialog.dismiss();
	            }

				private JSONObject calculatePosition(Way way) {
					double minLatitude = getMinLatitude(way);
					double maxLatitude = getMaxLatitude(way);
					double minLongitude = getMinLongitude(way);
					double maxLongitude = getMaxLongitude(way);
					double longitude = (minLongitude + maxLongitude)/2;
					double latitude = (minLatitude + maxLatitude)/2;
					JSONObject position = new JSONObject();
					try {
						position.put("latitude",""+latitude);
						position.put("longitude", ""+longitude);
					} catch (JSONException e) {
						
						return new JSONObject();
					}
					
					return position;
				}

				private double getMaxLongitude(Way way) {
					double maxLong = 0.0;
					for(Node node:way.getNodeList()){
						double longitude = node.getLocation().getLongitude();
						if( longitude > maxLong ) maxLong = longitude;
					}
						
					return maxLong;
				}

				private double getMinLongitude(Way way) {
					double minLong = 181.0;
					for(Node node:way.getNodeList()){
						double longitude = node.getLocation().getLongitude();
						if( longitude < minLong ){
							minLong = longitude;
						}
					}
					return minLong;
				}

				private double getMaxLatitude(Way way) {
					double maxLat = 0.0;
					for(Node node:way.getNodeList())
					{
						double latitude = node.getLocation().getLatitude();
						if( latitude > maxLat) maxLat = latitude;
					}
					return maxLat;
				}

				private double getMinLatitude(Way way) {
					double minLat=91.0;
					for(Node node:way.getNodeList())
					{
						double latitude = node.getLocation().getLatitude();
						if( latitude < minLat ) minLat = latitude;
					}
					return minLat;
				}
	        }.execute();
	        
	        dataDialog.show();
	    }
	};
    
    private ServiceConnection GPSReaderConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
        	myGPSReader = ((GPSReader.LocalBinder)service).getService(AssistiveCameraActivity.this);
        }
        
        public void onServiceDisconnected(ComponentName className) {
        	myGPSReader = null;
        }
    };

    void doUnbindService() {
        if (GPSReaderIsBound) {
            // Detach our existing connection.
            unbindService(GPSReaderConnection);
            GPSReaderIsBound = false;
        }
    }
    
	public void setGPSDisabled() {
		SpeechHandler.ttsQueue(getResources().getString(R.string.gpsDisabled), 0, 0);
		SpeechHandler.ttsQueue(getResources().getString(R.string.enableGPSDialog), 1, 0);
		SpeechHandler.ttsQueue(getResources().getString(R.string.exitAppDialog), 1, 0);
		
		builtGPSDialog();
	}
	
	public void setGPSEnabled() {	
		if (customizeDialog != null) {
			customizeDialog.hide();
			customizeDialog.dismiss();
		}
	}
	
	public void setStatus(int status) {
		String[] stingStatus = getResources().getStringArray(R.array.status);
		gpsStatus = stingStatus[status];
	}
    
    public void updateLocation(Location location, String status) {
    	if (myGPSReader.getProvider().equals(LocationManager.NETWORK_PROVIDER)||status == getResources().getString(R.string.fixed)) {
    		Log.d(TAG,"presnost: "+location.getAccuracy());
    		Log.d(TAG,"longitude:" + location.getLongitude());
    		Log.d(TAG,"latitude:" + location.getLatitude());
    		Log.d(TAG,"Altitude:" + location.getAltitude());
    		if (location.getAccuracy() <= 2000) {
    			this.location = location;
    			gpsStatus = getResources().getString(R.string.fixedString);
    			Log.d(TAG, "Location fixed. Accuracy:"+location.getAccuracy());
    		}
    		else{
    			Log.d(TAG,"Too bad accuracy: "+location.getAccuracy());
    		}
    	}
    }    
    
    public void builtGPSDialog() {
    	String title = ctx.getResources().getString(R.string.gpsStatusDialog);
    	title = title + ": " + ctx.getResources().getString(R.string.gpsDisabled);
    	String[] names = {ctx.getResources().getString(R.string.enableGPSDialog),
    			ctx.getResources().getString(R.string.exitAppDialog)};
        customizeDialog = new BlindDialog(ctx, this, title, names);
        customizeDialog.setCancelable(false);
        customizeDialog.show();
    }
    
    @Override
    protected void onResume() {
        super.onResume();
        		    
        GPSReaderIsBound = bindService(new Intent(AssistiveCameraActivity.this, GPSReader.class), 
        		GPSReaderConnection, Context.BIND_AUTO_CREATE);
        
        setContentView(mPreview);
        // Open the default i.e. the first rear facing camera.
        try {
        	// attempt to get a Camera instance
        	mCamera = Camera.open();
        } catch (Exception e){
            // Camera is not available (in use or does not exist)
        }
        mPreview.setCamera(mCamera);
        
        wakeLocker.acquire();
        
        isGalleryStarted = false;
        
		if (!SpeechHandler.getSpeechInitialization()) SpeechHandler.getInstance().ttsSetContext(this);
        
        SpeechHandler.ttsQueue(ctx.getResources().getString(R.string.start), 1, 0);
        SpeechHandler.ttsQueue(ctx.getResources().getString(R.string.landscapeOrientation), 1, 1);
        
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
        boolean previouslyStarted = prefs.getBoolean(getString(R.string.pref_previously_started_photo), false);
        if (!previouslyStarted) {
        	SharedPreferences.Editor edit = prefs.edit();
            edit.putBoolean(getString(R.string.pref_previously_started_photo), Boolean.TRUE);
            edit.commit();
            
            SpeechHandler.ttsQueue(ctx.getResources().getString(R.string.firstStartUpPhoto), 1, 1);
        }
        
        if (horizontalViewAngle == -1) {
           // horizontalViewAngle = mCamera.getParameters().getHorizontalViewAngle();
        	horizontalViewAngle = (float)49.55;
        	viewAngle = horizontalViewAngle;
        }
        
        if (OrientationManager.isSupported()) {
            OrientationManager.startListening(this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        
        SpeechHandler.getInstance().ttsStop();
        
        doUnbindService();
        
        wakeLocker.release();
        
        if (!isGalleryStarted) { 
        	SpeechHandler.getInstance().TTSDestroy();
            SpeechHandler.setSpeechInitialization(false); 
        }

        // Because the Camera object is a shared resource, it's very
        // important to release it when the activity is paused.
        if (mCamera != null) {
            mPreview.setCamera(null);
            mCamera.release();
            mCamera = null;
        }
        
        if (OrientationManager.isListening()) {
            OrientationManager.stopListening();
        }
        vib.cancel();
    }
    
    @Override
    protected void onDestroy() {
        super.onPause();
        SpeechHandler.getInstance().TTSDestroy();
        SpeechHandler.setSpeechInitialization(false); 
        
        finish();
    }
    
	@Override
	public void onPhotoOrientation(int orientation) {
		long[] pattern = { 0, 100, 50, 100, 50 };
		
		switch (orientation) {
	        case 0: 
	        	vib.vibrate(100);
	        	break;  
	        case 1: 
	        	viewAngle = horizontalViewAngle;
	        	vib.vibrate(pattern, -1);
	        	break;   
		}
	}

	@Override
	public void onOrientationChanged(float azimuth) {
		this.azimuth = azimuth;
	}

	@Override
	public void responseEvent(String response) {
		customizeDialog.hide();
		customizeDialog.dismiss();
		if (response.equals(ctx.getResources().getString(R.string.enableGPSDialog))) {
        	// application redirection to settings
            Intent gpsOptionsIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            gpsOptionsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(gpsOptionsIntent);
		} else if (response.equals(ctx.getResources().getString(R.string.exitAppDialog))) {
			AssistiveCameraActivity.this.finish();
		}
	}
}